package com.zhoug.widget.customview.pull;

import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

import com.zhoug.widget.R;

/**
 * 自定义下拉刷新容器
 */
public class PullToRefreshLayout extends ViewGroup {
    private static final String TAG = "PullToRefreshLayout";

    private View mTarget;

    private int maxDistance;//最大下拉距离: 默认2倍headerHeight
    private int minDistance;//最小下拉距离: 默认headerHeight
    private int refreshHeaderHeight;// header高度
    private int mTargetOffsetTop;
    private int mTouchSlop;

    private boolean isRefresh = false;

    private View mRefreshHeader;


    public PullToRefreshLayout(Context context) {
        this(context, null);
    }

    public PullToRefreshLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PullToRefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

        TextView textView = new TextView(context);
        textView.setText("下拉刷新");
        textView.setBackgroundColor(Color.WHITE);
        LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, 250);
        textView.setLayoutParams(layoutParams);
        setRefreshHeader(textView);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (mTarget == null) {
            ensureTarget();
        }
        if (mTarget == null) {
            return;
        }

        int childMaxWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
        int childMaxHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();

        //设置mTarget的大小
        mTarget.measure(MeasureSpec.makeMeasureSpec(childMaxWidth, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(childMaxHeight, MeasureSpec.EXACTLY));

        //刷新控件的大小
        measureChild(mRefreshHeader, widthMeasureSpec, heightMeasureSpec);

        if (refreshHeaderHeight <= 0) {
            refreshHeaderHeight = mRefreshHeader.getMeasuredHeight();
            if (minDistance <= 0) {
                minDistance = refreshHeaderHeight;
            }
            if (maxDistance <= 0) {
                maxDistance = refreshHeaderHeight * 2;
            }
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        if (getChildCount() == 0) {
            return;
        }
        if (mTarget == null) {
            ensureTarget();
        }
        if (mTarget == null) {
            return;
        }


//        Log.d(TAG, "onLayout: ");
        //子组件相对于父组件的位置
        int targetLeft = getPaddingLeft();
        int targetTop = getPaddingTop() + mTargetOffsetTop;
        int targetWidth = mTarget.getMeasuredWidth();
        int targetHeight = mTarget.getMeasuredHeight();

        int headerLeft = (getMeasuredWidth() - mRefreshHeader.getMeasuredWidth()) / 2;
        //header放到target的上方，水平居中
        mRefreshHeader.layout(headerLeft, -refreshHeaderHeight + mTargetOffsetTop, headerLeft + mRefreshHeader.getMeasuredWidth(), mTargetOffsetTop);
        //target铺满屏幕
        mTarget.layout(targetLeft, targetTop, targetLeft + targetWidth, targetTop + targetHeight);
    }

    /**
     * 获取到目标组件
     */
    private void ensureTarget() {
        if (mTarget == null) {
            int childCount = getChildCount();
            if (childCount > 2) {
                throw new IllegalStateException("只能有一个子组件");
            }
            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                if (!child.equals(mRefreshHeader)) {
                    mTarget = child;
                    break;
                }
            }
        }
    }

    /**
     * 能否向上滚动
     *
     * @return
     */
    private boolean canChildScrollUp() {
        return mTarget.getScrollY() > 0 || mTarget.canScrollVertically(-1);

    }

    private float downY = 0f;
    private float lastY = 0;

    private boolean mIsBeingDragged = false;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {


        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.d(TAG, "onInterceptTouchEvent: ACTION_DOWN");
                downY = ev.getY();
                mIsBeingDragged = false;
                break;
            case MotionEvent.ACTION_MOVE:
                Log.d(TAG, "onInterceptTouchEvent: ACTION_MOVE");
                if (ev.getY() - downY > mTouchSlop) {
                    Log.d(TAG, "onInterceptTouchEvent: 拦截事件");
                    mIsBeingDragged = true;
                    lastY = ev.getY();
                }
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                mIsBeingDragged = false;
                Log.d(TAG, "onInterceptTouchEvent: ACTION_UP");

                break;


        }


        return mIsBeingDragged;
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
         super.onTouchEvent(event);

        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
//                Log.d(TAG, "onTouchEvent: ACTION_MOVE");
                if (!mIsBeingDragged) {
                    if (event.getY() - downY > mTouchSlop) {
                        mIsBeingDragged = true;
                        lastY = event.getY();
                    }
                } else {
                    float moveY = event.getY();
                    int offset = (int) (moveY - lastY);
                    lastY = moveY;
                    Log.d(TAG, "onTouchEvent: offset=" + offset);
                    setOffsetTopAndBottom(offset);

                }


                break;
            case MotionEvent.ACTION_DOWN:
                Log.d(TAG, "onTouchEvent: ACTION_DOWN");
                downY = event.getY();

                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                Log.d(TAG, "onTouchEvent: ACTION_UP");
                mIsBeingDragged = false;
                if (mTargetOffsetTop < minDistance) {
                    reset();
                } else {
                    refresh();

                }


                break;
        }

        return true;
    }

    /**
     * 设置 header 相对于上次位置的偏移量
     *
     * @param offset
     */
    private void setOffsetTopAndBottom(int offset) {
        if (offset == 0) {
            return;
        }
        //header已经隐藏了 不能再上滑
        if (mTargetOffsetTop == 0 && offset < 0) {
            Log.d(TAG, "setOffsetTopAndBottom: 不能再上滑");
            return;
        }
        //header已经下拉到最大距离了
        if (mTargetOffsetTop == maxDistance && offset > 0) {
            Log.d(TAG, "setOffsetTopAndBottom: 已经下拉到最大距离了");
            return;
        }

        int newTargetOffsetTop = mTargetOffsetTop + offset;
        if (newTargetOffsetTop < 0) {
            offset = -mTargetOffsetTop;
        } else if (newTargetOffsetTop > maxDistance) {
            offset = maxDistance - mTargetOffsetTop;
        }
        mTarget.offsetTopAndBottom(offset);
        mRefreshHeader.offsetTopAndBottom(offset);
        mTargetOffsetTop = mTarget.getTop();

        if (mTargetOffsetTop < minDistance) {
            ((TextView) mRefreshHeader).setText("下拉刷新");
        } else if (mTargetOffsetTop == minDistance) {
            ((TextView) mRefreshHeader).setText("正在刷新");
            isRefresh=true;
        }
            else{
            ((TextView) mRefreshHeader).setText("释放开始刷新");
        }


        invalidate();
    }



    private void reset() {
        Log.d(TAG, "reset: ");
        ValueAnimator valueAnimator = ValueAnimator.ofInt(mTargetOffsetTop, 0);
        valueAnimator.setDuration(200);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addUpdateListener(listener -> {
            int newTop = (int) listener.getAnimatedValue();
            int offset =  newTop-mTargetOffsetTop;
            Log.d(TAG, "reset: offset="+offset);
            setOffsetTopAndBottom(offset);

        });
        valueAnimator.start();
    }

    private void refresh() {
        Log.d(TAG, "refresh: ");
        ValueAnimator valueAnimator = ValueAnimator.ofInt(mTargetOffsetTop, minDistance);
        valueAnimator.setDuration(200);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addUpdateListener(listener -> {
            int newTop = (int) listener.getAnimatedValue();
            int offset =  newTop-mTargetOffsetTop;
            Log.d(TAG, "reset: offset="+offset);
            setOffsetTopAndBottom(offset);

        });
        valueAnimator.start();
    }

    /**
     * 设置自定义header
     *
     * @param refreshHeader
     */
    public void setRefreshHeader(View refreshHeader) {
        if (refreshHeader != null && refreshHeader != mRefreshHeader) {
            LayoutParams layoutParams = refreshHeader.getLayoutParams();
            if (layoutParams == null) {
                layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
                refreshHeader.setLayoutParams(layoutParams);
            }
            this.mRefreshHeader = refreshHeader;
            addView(refreshHeader, 0);
        }
    }
}
